package cn.keniykey.mc.landterritory.land.api;

import java.util.List;
import java.util.UUID;

import javax.annotation.Nullable;

import org.bukkit.Location;
import org.bukkit.entity.Player;

import cn.keniykey.mc.landterritory.config.ConfigurationManager;
import cn.keniykey.mc.landterritory.land.LandManager;
import cn.keniykey.mc.landterritory.landflag.LandFlag;
import cn.keniykey.mc.landterritory.landflag.LandFlagManager;
import cn.keniykey.mc.landterritory.landflag.api.ILandFlagAuthority;
import cn.keniykey.mc.landterritory.landflag.api.LandFlagSetting;
import cn.keniykey.mc.landterritory.vault.Perm;

public final class LandUtil {
	
	public enum ELandPermissionLevel {
		OP(0),
		ADMIN(1),
		OWNER(2),
		FLAG_LANDADMIN(3),
		FLAG_FLAGADMIN(4);
		
		private final int perlevel;
		
		private ELandPermissionLevel(int level) {
			this.perlevel = level;
		}
		
		public int getLevel() {
			return this.perlevel;
		}
		@Nullable
		public ELandPermissionLevel nextLowLevel() {
			final int next = (this.perlevel + 1);
			for(final ELandPermissionLevel le : values()) {
				if(le.perlevel == next) return le;
			}
			return null;
		}
	}
	
	/**
	 * 判断玩家是否有管理权限
	 */
	public static boolean hasAdminPer(Player player,String world) {
		if(ConfigurationManager.AdminPer == null) return true;
		return Perm.getPerm().hasPermission(world, player, ConfigurationManager.AdminPer);
	}
	public static boolean hasLandPermission(Player player,Land land,ELandPermissionLevel minlevel) {
		ELandPermissionLevel level = ELandPermissionLevel.OP;
		while(level != null && level.getLevel() <= minlevel.getLevel()) {
			switch(level) {
			case OP:
				if(player.isOp()) return true;
				break;
			case ADMIN:
				if(hasAdminPer(player, land.getRange().getWorldName())) return true;
				break;
			case OWNER:
				if(!land.isSystem() && land.getOwner().equals(player.getUniqueId())) return true;
				break;
			default:
				if(hasLandAuthorityPermission(player, land, minlevel)) return true;
			}
			level = level.nextLowLevel();
		}
		return false;
	}
	private static boolean hasLandAuthorityPermission(Player player,Land land,ELandPermissionLevel minlevel) {
		for(final LandFlag flag : LandFlagManager.getFlagManager().getLandFlags()) {
			final String flagname = flag.getName();
			final ILandFlagAuthority auth;
			switch(minlevel) {
			case FLAG_LANDADMIN:
				auth = LandFlagSetting.getLandAuthority(flagname);
				break;
			case FLAG_FLAGADMIN:
				auth = LandFlagSetting.getFlagAuthority(flagname);
				break;
			default:
				auth = null;
			}
			if(auth == null || !land.getFlags().containsKey(flagname)) continue;
			try {
				if(auth.hasFlagPermissions(player, land)) return true;
			}catch(Exception ex) {
				ex.printStackTrace();
			}
		}
		return false;
	}
	public static int getMinDistanceXZ(Location loc,LandRange range) {
		range.fit();
		final int loc_x = loc.getBlockX();
		final int loc_z = loc.getBlockZ();
		final int x1 = Math.abs(loc_x - range.getLandPointOne().getX());
		final int x2 = Math.abs(loc_x - range.getLandPointTwo().getX());
		final int z1 = Math.abs(loc_z - range.getLandPointOne().getZ());
		final int z2 = Math.abs(loc_z - range.getLandPointTwo().getZ());
		return Math.min(Math.min(x1, x2), Math.min(z1, z2));
	}
	public static int getPlayerUsedLandLimit(UUID player_uuid) {
		final List<Land> list_lands = LandManager.getLandManager().getPlayerLands(player_uuid);
		if(list_lands.isEmpty()) return 0;
		int amount = 0;
		for(final Land land : list_lands) {
			switch(land.getType()) {
			case TERRITORY:
			case COMMUNITY:
				amount++;
			default:
			}
		}
		return amount;
	}
	public static boolean canHasNewLand(UUID player_uuid,ELandType type) {
		switch(type) {
		case GROUND:
			return true;
		default:
		}
		return LandManager.getLandManager().getPlayerLandLimit(player_uuid) > getPlayerUsedLandLimit(player_uuid);
	}
}